package com.haiheng.library_base.rabbitmq

import android.content.Intent
import android.util.Log
import com.google.gson.Gson
import com.haiheng.library.log.LogUtils
import com.haiheng.library.log.LogWriter
import com.haiheng.library_base.utils.NotificationUtils
import com.rabbitmq.client.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.IOException
import java.util.concurrent.TimeoutException


/**
 *
 * @Des:
 * @Author: hwz
 * @Date:2024/3/12 0012
 * @Version: 1.0
 */


object  RabbitmqHelper {
    private val TAG = "RabbitmqHelper"
    private val mConnectFactory by lazy { ConnectionFactory() }
//    private lateinit var mChannel: Channel

    val mqSettings = MQSettings(
        request_queue = "AIALGORITHMCENTER",
        exchange = "AIALMainhcraineventbusHC",
        routing_key = "MqYWIntegrationEvent",
        public_address = "http://172.16.0.145:8888/home/yc/visual_inventory_system/",
        rabbitmq_host = "218.17.192.252",
        rabbitmq_port = 5672,
        rabbitmq_username = "admin",
        rabbitmq_password = "hechaoadmin",
        virtual_host = "smartbookshelf"
    )
    init {
        // 初始化连接工厂
        mConnectFactory.apply {
            // 设置连接参数
            virtualHost = mqSettings.virtual_host
            host = mqSettings.rabbitmq_host
            port = mqSettings.rabbitmq_port
            username = mqSettings.rabbitmq_username
            password = mqSettings.rabbitmq_password
            isAutomaticRecoveryEnabled = true
        }
        // 创建一个通道
//        mChannel = mConnectFactory.newConnection().createChannel()
    }


    // 订阅消息
    fun subscribe( consumerFunction: (String) -> Unit) {
        GlobalScope.launch(Dispatchers.IO) {
            try {
                val connection = mConnectFactory.newConnection()
                val channel = connection.createChannel()
                var queueName = mqSettings.request_queue
                channel.queueDeclare(queueName, true, false, false, null)
                channel.queueBind(queueName, mqSettings.exchange, mqSettings.routing_key)

                val consumer = object : DefaultConsumer(channel) {
                    override fun handleDelivery(
                        consumerTag: String?,
                        envelope: Envelope,
                        properties: com.rabbitmq.client.AMQP.BasicProperties?,
                        body: ByteArray?
                    ) {
                        val message = body?.toString(Charsets.UTF_8)
                        message?.let { consumerFunction(it) }
                    }
                }
                channel.basicConsume(queueName, true, consumer)
            } catch (e: Exception) {
                e.printStackTrace()
                LogUtils.w("${TAG} 订阅消息 异常：${e}")
            }
        }

    }


/*    fun subscribe(messageHandler: (String) -> Unit) {
        // 订阅消息
        Thread {
            try {
                val connection = connectFactory.newConnection()
                val channel = connection.createChannel()
                channel.basicQos(1)
//                channel.exchangeDeclare(mqExchange, "fanout", true)
//                channel.queueDeclare(mqMessageQueueName, true, false, false, null)
                channel.queueBind(mqMessageQueueName, mqExchange, mqRoutingKey)

                val consumer = object : DefaultConsumer(channel) {
                    override fun handleDelivery(
                        consumerTag: String?,
                        envelope: Envelope,
                        properties: AMQP.BasicProperties?,
                        body: ByteArray?
                    ) {
                        val message = body?.let { String(it) }
                        message?.let {
                            messageHandler(it)
                            channel.basicAck(envelope.deliveryTag, false)
                        } ?: run {
                            LogUtils.e("${TAG} Received empty message body")
                            channel.basicReject(envelope.deliveryTag, false)
                        }
                    }
                }
                channel.basicConsume(mqMessageQueueName, false, consumer)
            } catch (e: Exception) {
                LogUtils.e("${TAG} Failed to subscribe: ${e}")
            }
        }.start()
    }*/

    /**
     * TODO通过调用 basicPublish 方法，生产者可以将消息发布到指定的交换机，并且消息会被根据交换机的路由规则路由到相应的队列中，供消费者进行消费。
     *
     * @param message
     * xchange：要发送消息的目标交换机的名称。
     * routingKey：消息的路由键，用于将消息路由到与之匹配的队列。在不同类型的交换机中，路由键的匹配规则可能有所不同。
     * props：消息的属性，例如消息的持久化属性、优先级等。
     * body：消息的内容，通常是以字节数组的形式表示的消息体。
     */
    // 发送消息
    fun publish(message: String) {
        GlobalScope.launch(Dispatchers.IO) {
            try {
                val connection = mConnectFactory.newConnection()
                val channel = connection.createChannel()
                channel.basicPublish(mqSettings.exchange, mqSettings.request_queue, null, message.toByteArray())
                channel.close()
                connection.close()
            } catch (e: Exception) {
                e.printStackTrace()
                LogWriter.e("${TAG} 发送消息异常：${e}")
            }
        }
    }

  /*  fun publish(message: String) {
        // 发布消息
        Thread {
            var connection: Connection? = null
            var channel: Channel? = null
            try {
                connection = connectFactory.newConnection()
                channel = connection.createChannel()
                //用于将消息发布到指定的交换机
                channel.basicPublish("", mqMessageQueueName, null, message.toByteArray())
            } catch (e: Exception) {
                LogUtils.e("${TAG} Failed to publish message: ${e.message}")
            } finally {
                try {
                    channel?.close()
                    connection?.close()
                } catch (e: IOException) {
                    LogUtils.e("${TAG} Failed to close channel or connection: ${e.message}")
                } catch (e: TimeoutException) {
                    LogUtils.e("${TAG} Failed to close channel or connection: ${e.message}")
                }
            }
        }.start()
    }*/
}
